#pragma once
#ifndef TOFTLIB_BASEEXTENDEXCEPTION_H
#define TOFTLIB_BASEEXTENDEXCEPTION_H

/**
 * @file BaseExtendedException.h
 * @author ActiveMQ
 */

#include <Windows.h>
#include <string>
#include "ExtendedException.h"

namespace toftlib
{
    class BaseExtendedException : public ExtendedException
    {
    public:
        BaseExtendedException(void) throw();
        BaseExtendedException(const BaseExtendedException& ex) throw();
        BaseExtendedException(const wchar_t* file, const int lineNumber, const wchar_t* msg, ... ) throw();
        virtual ~BaseExtendedException(void) throw();

        /**
         * Gets the message for this exception.
         *
         * @return Text formatted error message
        */
        virtual std::wstring getMessage() const
        {
            return message;
        }


        /**
         * Implement method from std::exception
         *
         * @return the const char* of <code>getMessage()</code>.
         */
        virtual const char* what() throw ();

        /**
         * Sets the cause for this exception.
         *
         * @param msg the format string for the msg.
         * @param variable - params to format into the string
         */
        virtual void setMessage( const wchar_t* msg, ... );

        /**
         * Adds a file/line number to the stack trace.
         *
         * @param file The name of the file calling this method (use __FILE__).
         * @param lineNumber The line number in the calling file (use __LINE__).
         */
        virtual void setMark( const wchar_t* file, const int lineNumber );

        /**
         * Clones this exception.  This is useful for cases where you need
         * to preserve the type of the original exception as well as the message.
         * All subclasses should override.
         *
         * @return Copy of this Exception object
         */
        virtual BaseExtendedException* clone() const;

        /**
         * Provides the stack trace for every point where
         * this exception was caught, marked, and rethrown.  The first
         * item in the returned vector is the first point where the mark
         * was set (e.g. where the exception was created).
         *
         * @return the stack trace.
         */
        virtual std::vector< std::pair< std::wstring, int> > getStackTrace() const;

        /**
         * Prints the stack trace to std::werr
         */
        virtual void printStackTrace() const;

        /**
         * Prints the stack trace to the given output stream.
         *
         * @param stream the target output stream.
         */
        virtual void printStackTrace( std::wostream& stream ) const;

        /**
         * Gets the stack trace as one contiguous string.
         *
         * @return string with formatted stack trace data
         */
        virtual std::wstring getStackTraceString() const;

        /**
         * Assignment operator.
         *
         * @param const reference to another BaseExtendedException
         */
        virtual BaseExtendedException& operator =( const BaseExtendedException& ex );

    protected:
        virtual void buildMessage( const wchar_t* format, va_list& vargs );

    private:
        /**
         * The cause of this exception.
         */
        std::wstring message;

        /**
         * ASCII cause of this exception
         */
        std::string ascMessage;

        /**
         * The stack trace.
         */
        std::vector< std::pair< std::wstring, int> > stackTrace;
    };
}

#endif
